package com.mybooksystem.springboot.controller;


import com.mybooksystem.springboot.config.Result;
import com.mybooksystem.springboot.service.LoginService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.http.HttpCookie;
import org.springframework.web.bind.annotation.*;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import javax.websocket.server.PathParam;
import java.text.SimpleDateFormat;
import java.util.*;

/**
 * 与登录相关的前端控制器。
 */
@RestController
public class LoginPageController extends BaseController {

    @Autowired
    @Qualifier("loginService")
    private LoginService loginService;

    //验证码
//    @Autowired
//    private Kaptcha kaptcha;


    //  /isUsername?username=zhangsan
    // 注册时，使用。
//    @GetMapping("/isUsername")

    /**
     * 用于判断是否有该管理员。
     * @param username：管理员姓名。
     * @return
     */
    @PostMapping("/isUsername")
    public Map<String,String> isUsername(@PathParam("username") String username){
        System.out.println("isUsername 执行了。。。。。。");
        System.out.println("username："+username);


//        loginService.isUsername(username) ?
        //查询服务层是否含有该用户。
        if (loginService.isUsername(username)){
            //用户名正确
//            return "{isUsername:true}";   //回传的是 string 类型
            HashMap<String, String> map = new HashMap<>();
            map.put("isUsername", String.valueOf(true));
            return map;//回传 json
        }
        //用户名不正确
//        return "{isUsername:false}";      //回传的是 string 类型
        HashMap<String, String> map = new HashMap<>();
        map.put("isUsername", String.valueOf(false));
        return map; //回传 json
    }

    //发送手机验证码
    //发送邮箱验证码



    //使用 kaptcha依赖包

    // 日期格式化对象
    private final SimpleDateFormat ft = new SimpleDateFormat("yyyy-MM-dd kk:mm:ss");
    private final Date date = new Date();

    /**
     * 获取验证码。
     * 每次获取验证码时需要把之前的验证码销毁。
     *
     * @param data 当前时间。
     */
    //获取验证码
    @GetMapping("/code.jpg")
    public void render(HttpServletResponse response, @RequestParam(value = "d",required = false) Long data) {
        try {
            // 生成验证码。
            CodeCaptcha.getCode(response);
            if (data!=null){
                date.setTime(data);
                System.out.println("时间："+ ft.format(date));
            }
            System.out.println("验证码生成：" + CodeCaptcha.code);
        } catch (Exception e) {
            e.printStackTrace();
        }

    }

    /**
     * 建议别使用 kaptcha依赖包 中的 validate()，因为只能验证一次。
     *
     * 暂时 bug 未解决。明天再搞！
     *
     * @param code
     * @return
     */
//    @GetMapping("/isCode")
//    public Map<String,String> isCode(@PathParam("code") String code){
//        HashMap<String , String > map = new HashMap<>();
//        //校验验证码，校验字符串 和 验证超时时间(5分钟=300s)。一旦返回true之后，再次调用会报 com.baomidou.kaptcha.exception.KaptchaNotFoundException: null。
//        map.put("isCode",String.valueOf(kaptcha.validate(code, 300)));
//        return map;
//    }
















    /**
     *  登录操作暂时不支持并发。<br>
     *
     *  登录操作，进行判断 【用户名】 和 【密码】 、【验证码】 是否正确。<br>
     *   bug：后退和前进可在登录页面和后台管理系统来回横跳。【原因：浏览器缓存】<br>
     *
     *  登录成功之后会存放两个 session<br>
     *  &emsp;          1、一个名为 loginSession ，<br>
     *  &emsp;&emsp;        用于防止不登录直接进入后台管理系统。【由拦截器进行拦截】<br>
     *  &emsp;          2、一个名为 username ，<br>
     *  &emsp;&emsp;        用于进行登录之后的用户名展示。<br>
     *
     * 关于密码加密问题。<br>
     *      由后端生成一个秘钥给前端，前端发送密码时会加上该秘钥进行发送。【未做】<br>
     *
     *
     * @param username 用户名。
     * @param password 密码。【密码需要进行加密，加密未做】
     * @param code 验证码。
     * @return
     *      返回json形式的结果。<br>
     *      回传格式：<br>
     *      {   <br>
     * &emsp;          code: 状态码.<br>
     * &emsp;          msg:  状态码的提示信息。<br>
     * &emsp;          data: 数据。<br>
     * &emsp;&emsp;    {    <br>
     * &emsp;&emsp;&emsp;   content: 提示信息.<br>
     * &emsp;&emsp;&emsp;   page: 登录成功的页面。<br>
     * &emsp;&emsp;    }    <br>
     *
     *      }<br>
     */
//    @GetMapping("/login")
    @PostMapping("/login")
    public Result<Map<String, String>> login(
            @RequestParam(value = "username",required = false) String username,
            @RequestParam(value = "password",required = false) String password,
            @RequestParam(value = "code",required = false) String code,
            @RequestHeader("Referer") String referer,
//            @SessionAttribute("JSESSIONID") String jsId,  // 获取失败
            @CookieValue("JSESSIONID") String jsId,     // 获取成功！JSESSIONID：是用户验证。【随着用户窗口关闭而消失】

            HttpServletRequest request,
            HttpSession session
    ) {

        System.out.println("登录操作！");
        //获取用户登录的操作
        System.out.println("用户信息（username）：\t" + username);
        System.out.println("用户信息（password）：\t" + password);
        System.out.println("用户信息（code）：\t" + code);
        System.out.println("当前 session ：\t" + jsId);

/*
        System.out.println("当前会话（JSESSIONID）：" + request.getSession().getAttribute("JSESSIONID"));
        Enumeration<String> cookie = request.getHeaders("Cookie");
         // 将数据遍历出来

        while(cookie.hasMoreElements()) {
            //遍历枚举中存储的每一个元素
            String value = (String) cookie.nextElement();
            System.out.println("当前 cookie：" + value);//将值输出
        }
        cookie.asIterator().forEachRemaining(System.out::println);

        String[] cookie1 = request.getHeader("Cookie").split("; ");
        for (String cookie : cookie1) {
            // 判断字符串是否以 JSESSIONID 开头。
            if (cookie.startsWith("JSESSIONID")){
                String[] split = cookie.split("=");
                System.out.println("key：" + split[0]);
                System.out.println("value：" + split[1]);
            }
        }
        System.out.println("================================");
        Arrays.stream(cookie1).forEach(System.out::println);
*/

//        int i = 10/0;
        Map<String, String> map = new HashMap<>();

        try {   //可能引发并发的问题。
                // 验证码不正确。
    //        if (!this.code.equals(code)){
            if (!CodeCaptcha.code.equalsIgnoreCase(code)){
                System.out.println("验证码不正确！！");
                map.put("content","验证码不正确！");
                return new Result<>(400,"失败！",  map);
            }
            // 销毁验证码
    //        kaptcha.validate(code, 500);
            CodeCaptcha.destroy();
        } catch (Exception e) {
            e.printStackTrace();
            System.out.println("该验证码已被使用！");
            map.put("content","该验证码已被使用！");
            return new Result<>(499,"失败！",  map);

        }

        try {
            // 查询用户是否存在。
            if (loginService.loginState(username,password)){
                //成功并回传后台管理页面！
                map.put("page","/managementSystem");
                map.put("content","登录成功");
                session.setAttribute("username",username);  // 服务器保存。

                // 设置登录状态的 session。该 UUID 必须是static，否则会在使用地为null。
                uuid = UUID.randomUUID().toString();
                // 每次访问首页是会去设置一个id。
                session.setAttribute("loginSession", uuid);

//                System.out.println("登录成功！");
                // 登录状态。
//                System.out.println("session: ==> （loginSession）：" + session.getAttribute("loginSession"));
                // 用户信息。
//                System.out.println("session: ==> （username）：" + session.getAttribute("username"));

                return new Result<>(200,"成功！",  map);
            }else {
                //失败，并回传错误信息！
                map.put("content","用户名或密码错误");
                // 重新绘制验证码。[前端进行重新绘制]
                // 失败之后
                return new Result<>(400,"失败！",  map);
            }
            // 该错误是服务器出现了问题。出现该错误，则说明是数据库连接的问题。
//        } catch (CommunicationsException e) {
        } catch (Exception e) {
            System.out.println("服务器出问题了");
            e.printStackTrace();
            //失败，并回传错误信息！
            map.put("content","服务器出问题了");
            // 失败之后
            return new Result<>(500,"失败！",  map);
        }
    }
}
